package com.happy_hao.topbiz.config;

import com.happy_hao.topbiz.exception.ServiceException;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.pam.AuthenticationStrategy;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import java.util.Collection;

public class CustomAuthenticationStrategy implements AuthenticationStrategy {

    @Override
    public AuthenticationInfo beforeAllAttempts(
            Collection<? extends Realm> realms, AuthenticationToken token)
            throws AuthenticationException {

        return null;
    }

    @Override
    public AuthenticationInfo beforeAttempt(
            Realm realm, AuthenticationToken token, AuthenticationInfo aggregate)
            throws AuthenticationException {

        return aggregate;
    }

    @Override
    public AuthenticationInfo afterAttempt(
            Realm realm, AuthenticationToken token,
            AuthenticationInfo singleRealmInfo, AuthenticationInfo aggregate,
            Throwable throwable) throws AuthenticationException {

        if (throwable != null) {
            if (throwable instanceof UnknownAccountException) {
                throw new ServiceException("用户不存在");
            }
            if (throwable instanceof IncorrectCredentialsException) {
                throw new ServiceException(throwable.getMessage());
            }
            throw new AuthenticationException("Realm 认证异常", throwable);
        }

        return mergeAuthenticationInfo(singleRealmInfo, aggregate, realm);
    }

    @Override
    public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
        if (aggregate == null) {
            throw new UnknownAccountException("没有Realm认证成功");
        }
        return aggregate;
    }

    private AuthenticationInfo mergeAuthenticationInfo(
            AuthenticationInfo newInfo,
            AuthenticationInfo aggregate,
            Realm realm) {

        if (newInfo == null) {
            return aggregate;
        }

        if (aggregate == null) {
            return newInfo;
        }

        // 1. 合并主体集合（PrincipalCollection）
        PrincipalCollection newPrincipals = newInfo.getPrincipals();
        PrincipalCollection aggregatePrincipals = aggregate.getPrincipals();

        // 创建新的主体集合（可修改的）
        SimplePrincipalCollection mergedPrincipals = new SimplePrincipalCollection();

        // 添加聚合主体
        if (aggregatePrincipals != null && !aggregatePrincipals.isEmpty()) {
            mergedPrincipals.addAll(aggregatePrincipals);
        }

        // 添加新主体
        if (newPrincipals != null && !newPrincipals.isEmpty()) {
            mergedPrincipals.addAll(newPrincipals);
        }

        // 2. 创建合并后的认证信息
        SimpleAuthenticationInfo mergedInfo = new SimpleAuthenticationInfo(
                mergedPrincipals,
                aggregate.getCredentials(), // 通常只使用第一个凭证
                realm.getName()
        );

        // 3. 复制其他属性（如有）
        if (aggregate instanceof SimpleAuthenticationInfo) {
            SimpleAuthenticationInfo saInfo = (SimpleAuthenticationInfo) aggregate;
            mergedInfo.setCredentialsSalt(saInfo.getCredentialsSalt());
        }

        return mergedInfo;
    }
}
